home *** CD-ROM | disk | FTP | other *** search
/ Die Ultimative Software-P…i Collection 1996 & 1997 / Die Ultimative Software-Pakete CD-ROM fur Atari Collection 1996 & 1997.iso / i / internet / software / tnftpsr / tn.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-09-01  |  48.5 KB  |  1,807 lines

  1. /*     ANS compatible Telnet in AES windows     */
  2. /*         compiled with TURBO-C/PURE-C         */
  3. /*   P. Mayer & H. Wieser TU Vienna  1992,1993  */
  4.  
  5. #define NET
  6.  
  7. #include <aes.h>            
  8. #include <vdi.h>
  9. #include <stdio.h>
  10. #include <string.h>
  11. #include <errno.h>
  12. #include <tos.h>
  13. #include <stdlib.h>
  14. #include <ext.h>
  15. #include <ctype.h>
  16. #include "tnftp.h"    /* output from RCS */
  17. #include "tndefs.h"    /* various definitions */
  18. #include "tcpdef.h"    /* tcp layer defs */
  19.  
  20. #ifdef SYSFONTS
  21. #include <linea.h>
  22. #endif
  23.  
  24. #define TELNET_PORT     23
  25. #define FTP_CTL     21
  26. #define FTP_DATA     20
  27.  
  28. #define XFTP     0
  29. #define TN     1
  30. #define FTP     2
  31.  
  32. #define VERSION "1.35d"
  33.  
  34. extern int ftpinit(struct wi_str *wp, char *user, char *passwd);
  35. extern int ftp_application(struct wi_str *);
  36. extern void handle_key(struct wi_str *, char key);
  37. extern char *getmem();  /* in winsubr.c */
  38. extern void loadfont (char *);
  39. extern void startup(void);
  40. extern void finish(void);
  41. extern int get_pipe(char *, int *, int *);
  42. extern int s_dial(int, int);
  43. extern void set_menu_string(char *, int);
  44. extern int size_dial(int *, int *);
  45. extern int xatoi(char *);
  46. extern void do_editkeys(void);
  47. extern char *getmem(long size);
  48. extern int w_open(char *name, int xpos, int ypos, int xsiz, int ysiz, int sliders, int titles, FNT *usefont);
  49. extern void w_closei(struct wi_str *wp);
  50. extern void w_close(struct wi_str *wp);
  51. extern int w_resize(struct wi_str *wp1, int xsiz, int ysiz, int sliders, int titles, int chfont);
  52. extern void w_rename(struct wi_str *wp, char *name);
  53. extern void w_info(struct wi_str *wp, char *name);
  54. extern void w_redraw(struct wi_str *wp, int logic, int xx, int yy, int ww, int hh);
  55. extern void w_update(struct wi_str *wp, int logic, int xx, int yy, int ww, int hh);
  56. extern void w_move(struct wi_str *wp, int xx, int yy, int ww, int hh);
  57. extern void w_top(struct wi_str *wp);
  58. extern void w_bottom(void);
  59. extern void w_hide(void);
  60. extern void w_shrink(struct wi_str *wp);
  61. extern void w_full(struct wi_str *wp);
  62. extern void w_arrow(struct wi_str *wp, int arrow);
  63. extern void w_slide(struct wi_str *wp, int hor, int val);
  64. extern void sethslide(struct wi_str *wp);
  65. extern void w_output(struct wi_str *wp, unsigned char *ptr, short charcount);
  66. extern void lineerase(register struct wi_str *wp, int first, int last);
  67. extern void setvslide(struct wi_str *wp);
  68. extern void w_flash(struct wi_str *wp, int state);
  69. extern void scrollup(register struct wi_str *wp, int first, int nlines, int amount);
  70. extern void scrolldn(register struct wi_str *wp, int first, int nlines, int amount);
  71. extern int upcall(struct wi_str *wp);
  72. extern int tnet(struct wi_str *wp, long key);
  73. extern int connect(int port, char * host, int tcp_id);
  74. extern void printw(struct wi_str *wp, char * text);
  75. extern int tcp_out(int tcp_id, char *o_str, int o_len);
  76.  
  77. int get_string(char *prompt, char *string);
  78. int get_host(char *prompt, char *string);
  79. void invert(struct wi_str *wp,int x1,int y1,int x2, int y2);
  80. char char_at(struct wi_str *wp, int x_loc, int y_loc);
  81. int do_multi(int mode);
  82. void newopen(void);
  83.  
  84. extern int ftpbusy;
  85. extern char data[];
  86. #ifdef SYSFONTS
  87. extern FONTS *Fonts;
  88. #endif
  89.  
  90. static char infpath[MAXPATH];
  91. static char hostname[MAXPARLEN], user[MAXPARLEN], passwd[MAXPARLEN];
  92. static int work_in[11];
  93. static int work_out[57];
  94. static int msgbuff[8];
  95. static char line[MAXCOL * MAXROW + 1];
  96. static int len;
  97. static int timeint;
  98. static int phys_handle;
  99. static int active, menu_id, appl_id;  /* used to indicate opened ACC */
  100. static int key;
  101.  
  102. /*
  103.  * Character stuff (fonts).
  104.  */
  105. static FNT    *fnttbl[10];  /* List of pointers to fonts avail */
  106. static int    fontsavail;  /* Number of fonts available */
  107. static int    fntnum = 1;  /* index of font in fonttable */
  108.  
  109. static int fontmenuobj[] = 
  110. {  /* array of font menu object numbers */
  111.   FNT8X8,
  112.   FNT8X16,
  113.   FNT6X7,
  114.   FNTOWN,
  115.   FNTALT,
  116.   FNTTNY,
  117.   FNTOTH,
  118.   /* Add new font menu items here! */
  119.   0
  120. };
  121.  
  122. static OBJECT *menubar;  /* used in startup & finish */
  123. static char *caps_table;  /* keyboard table for caps-locked keys (sigh) */
  124. static int sliders = 0;  /* set by menu items, arguments to w_open */
  125. static int titles = 1;
  126. static int xsiz, ysiz;
  127. static int last_x = 132, last_y = 24;  /* last size you asked for in SHELLOTH */
  128.  
  129. int ftp_ctl, ftp_data;
  130. char keeppath[MAXPATH];
  131.  
  132. int screen_handle;
  133. int ncolors;  /* used by ESCb and ESCc */
  134. #ifndef NET
  135. char buf[1000];
  136. #endif
  137.  
  138. /* evnt_multi data return spaces */
  139. int sdummy;
  140.  
  141. /* "fast" controls "window flourish" (grow/shrink boxes) */
  142. int fast = 1;
  143.  
  144. /*
  145.  * jerky_updates controls whether or not you get an update before each
  146.  * non-printing character in the output stream.  With it on things are
  147.  * faster; with it off, things are smoother.
  148.  */
  149. int jerky_updates = 1;
  150.  
  151. /*
  152.  * mouseflicker controls just that: with it ON, the mouse flickers, but
  153.  * it is almost always visible: it gets turned off before redraws and
  154.  * immediately turned on afterwards.  With it OFF, the mouse is turned
  155.  * off before a redraw, then left off until it moves (or you quit or close
  156.  * the last window).
  157.  */
  158. int mouseflicker = 1;
  159. int audibell, visibell;  /* what to do on bell */
  160. int mouse;  /* visibility flag for mouse */
  161. int delmode = 0;    /* how to handle DEL and BS keys */;
  162. int wrap = 0;        /* how to treat wrap on eol */;
  163.  
  164. /*
  165.  * globals imported by winsubr
  166.  */
  167.  
  168. struct wi_str *wlist, *wsource;  /* a pointer into the window ring */
  169.  
  170. int scr_x, scr_y, scr_w, scr_h, wnum;  /* screen workxywh (?) */
  171. WIN_MFDB screen_mf;  /* mfdb for the screen */
  172. FNT *curfont;  /* ptr to current font (internal format(?)) */
  173.  
  174. /*
  175.  * Resource file first/last objects in menu bar. These have to be the first
  176.  * & last (numerically) which are allowed to have hot-keys assigned to
  177.  * them.  "About ..." is a poor choice since the items after that in the
  178.  * resource are the space-holders for the accessories.  So you can't bind
  179.  * a key to About... So what?  Big deal.
  180.  */
  181.  
  182. #define FIRSTOBJ DABOUT
  183. #define STARTOBJ MENUEDIT
  184. #define LASTOBJ REFONT
  185.  
  186.  
  187. /* read a font from a file */
  188. void loadfont (name)
  189. char *name;
  190. {
  191.   FNT * curfont;
  192.   char *tmpfnt;
  193.   char menustr[20];
  194.   char namestr[20];
  195.   int shift;
  196.   unsigned int mask;
  197.   int i;
  198.   char *getmem();
  199.   char x1,x2;
  200.  
  201.   if ((curfont = (FNT *) getmem((long)sizeof(FNT))) == NULL)
  202.     return;
  203.   i = Fopen(name, 0);
  204.   if (i<0) return;
  205.   (void)Fread(i, 4096L, curfont->f_data);
  206.   (void)Fclose(i);
  207.   curfont->inc_x = MINMAX(curfont->f_data[16], 1, 8);
  208.   curfont->inc_y = MINMAX(curfont->f_data[32], 1, 16);
  209.   curfont->nchars = 128;
  210.   curfont->f_data[16] = curfont->f_data[32] = 0;
  211.   shift = 8 - curfont->inc_x;
  212.   mask = (1 << curfont->inc_x) - 1;
  213.   tmpfnt = curfont->f_data;
  214.  
  215.   for (i=0; i < 4096; i++) 
  216.   {
  217.     *tmpfnt = (*tmpfnt>>shift)&mask;
  218.     tmpfnt++;
  219.   }
  220.   if(fontsavail == 1)
  221.   {
  222.     x1 = ALTINDICATOR;
  223.     x2 = 'N';
  224.   }
  225.   else if(fontsavail == 0)
  226.   {
  227.     x1 = ALTINDICATOR;
  228.     x2 = 'L';
  229.   }
  230.   else x1 = x2 = ' ';
  231.  
  232.   if(sscanf(name, "wind%3s", namestr))
  233.     sprintf(menustr, "%d x %2d %s font %c%c", curfont->inc_x, curfont->inc_y,
  234.     namestr,x1,x2);
  235.   else sprintf(menustr, "%d x %2d sys font %c%c", curfont->inc_x, curfont->inc_y,
  236.   x1,x2);
  237.   set_menu_string(menustr, fontmenuobj[fontsavail]);
  238.  
  239.   fnttbl[fontsavail] = curfont;
  240.   fontsavail++;
  241.   return;
  242. }
  243.  
  244. void setfonts(void)
  245. {
  246. #ifdef SYSFONTS
  247.   linea_init();
  248. #endif
  249.   /*
  250.          * now set up the system fonts
  251.          */
  252.   fontsavail = 0;
  253. #ifdef SYSFONTS  
  254.   if ((curfont = (FNT *)getmem((long)sizeof(FNT))) != NULL) 
  255.   {
  256.     tmpfnt = Fonts->font[1]->fnt_dta;  /* 8 x 8 system font */
  257.  
  258.     for (i=0; i<256; i++)
  259.       for (j=0; j<8; j++)
  260.         curfont->f_data[i*16+j] = tmpfnt[i+j*256];
  261.     curfont->inc_x = 8;
  262.     curfont->inc_y = 8;
  263.     curfont->nchars = 256;
  264.  
  265.     set_menu_string("8 x 8 sys font", fontmenuobj[fontsavail]);
  266.  
  267.     fnttbl[fontsavail] = curfont;
  268.     fontsavail++;
  269.   }
  270. #ifdef COPYFONTS
  271.   {
  272.     int fid;
  273.     fid = Fcreate("8x8sys.fnt",0);
  274.     Fwrite(fid,4096L,curfont->f_data);
  275.     Fclose(fid);
  276.   }
  277. #endif
  278.   if ((curfont = (FNT *)getmem((long)sizeof(FNT))) != NULL) 
  279.   {
  280.     tmpfnt = Fonts->font[2]->fnt_dta;  /* 8 x 16 system font */
  281.  
  282.     for (i=0; i<256; i++)
  283.       for (j=0; j<16; j++)
  284.         curfont->f_data[i*16+j] = tmpfnt[i+j*256];
  285.     curfont->inc_x = 8;
  286.     curfont->inc_y = 16;
  287.     curfont->nchars = 256;
  288.  
  289.     set_menu_string("8 x 16 sys font", fontmenuobj[fontsavail]);
  290.  
  291.     fnttbl[fontsavail] = curfont;
  292.     fontsavail++;
  293.   }
  294. #ifdef COPYFONTS
  295.   {
  296.     int fid;
  297.     fid = Fcreate("8x16sys.fnt",0);
  298.     Fwrite(fid,4096L,curfont->f_data);
  299.     Fclose(fid);
  300.   }
  301. #endif
  302.   /* set up 6 x 6 system font */
  303.   if ((curfont = (FNT *)getmem((long)sizeof(FNT))) != NULL) {
  304.     tmpfnt = Fonts->font[0]->fnt_dta;
  305.  
  306.     for (i=0; i<256; i++) 
  307.     {
  308.       int bitpos, index, offset;
  309.  
  310.       bitpos = i * 6;
  311.       index = bitpos >> 3;
  312.       offset = bitpos & ~(~0 << 3);
  313.       for (j=0; j<6; j++)  /* for each pixel row in character */
  314.         curfont->f_data[i*16+j+1] = ((tmpfnt[index+j*192] << offset) +
  315.             (tmpfnt[index + j*192 +1] >> (8-offset) & ~(~0 << offset)))  /*>> 2 & 0x3f*/;
  316.       curfont->f_data[i*16+0] = 0;  /* extra empty row */
  317.     }
  318.     curfont->inc_x = 6;
  319.     curfont->inc_y = 7;
  320.     curfont->nchars = 256;
  321.     /*
  322.          * The 6x6 system font can be made better.  (dot the i and j.)
  323.          * This is a bad hack, but it makes it easier to read.
  324.          */
  325.     curfont->f_data[105*16+1] = 20;
  326.     curfont->f_data[105*16+2] = 0;
  327.     curfont->f_data[105*16+5] = 20;
  328.     curfont->f_data[106*16+5] = 80;
  329.     curfont->f_data[106*16+6] = 20;
  330.     curfont->f_data[106*16+2] = 20;
  331.  
  332.     set_menu_string("6 x 7 sys font", fontmenuobj[fontsavail]);
  333.     fnttbl[fontsavail] = curfont;
  334.     fontsavail++;
  335.   }
  336. #ifdef COPYFONTS
  337.   {
  338.     int fid;
  339.     fid = Fcreate("6x7sys.fnt",0);
  340.     Fwrite(fid,4096L,curfont->f_data);
  341.     Fclose(fid);
  342.   }
  343. #endif
  344. #endif
  345. }
  346.  
  347. void update_help(void)
  348. {
  349.   int j = ABOUTTXT;
  350.   char *found, *targ;
  351.   OBJECT *obj_tmp;
  352.   int i;
  353.  
  354.   rsrc_gaddr(R_TREE, HELPTEXT, &obj_tmp);
  355.  
  356.   for (i = FIRSTOBJ; i <= LASTOBJ; i++) 
  357.   {
  358.     if(i > FIRSTOBJ && i < STARTOBJ) continue;
  359.     if ((menubar[i].ob_type == G_STRING) &&
  360.         (*(char *)menubar[i].ob_spec.free_string != '-'))
  361.     {
  362.       found = menubar[i].ob_spec.free_string;
  363.       targ = obj_tmp[j].ob_spec.free_string;
  364.       strncpy(targ,found+1,20L);
  365.       obj_tmp[j].ob_state = menubar[i].ob_state;
  366.       obj_tmp[j].ob_flags |= (EXIT + SELECTABLE); 
  367.       j++;
  368.     }
  369.   }
  370. }
  371.  
  372. void load_settings(void)
  373. {
  374.   FILE *fp;
  375.   int i;
  376.  
  377.   fp = fopen(infpath,"r");
  378.   if(fp)
  379.   {
  380.     fscanf(fp,"fast =%d\n",&fast);
  381.     fscanf(fp,"jerky =%d\n",&jerky_updates);
  382.     fscanf(fp,"wrap =%d\n",&wrap);
  383.     fscanf(fp,"del/bs =%d\n",&delmode);
  384.     fscanf(fp,"mouse =%d\n",&mouseflicker);
  385.     fscanf(fp,"sliders =%d\n",&sliders);
  386.     fscanf(fp,"titles =%d\n",&titles);
  387.     fscanf(fp,"width =%d\n",&last_x);
  388.     fscanf(fp,"height =%d\n",&last_y);
  389.     fscanf(fp,"audibell =%d\n",&audibell);
  390.     fscanf(fp,"visibell =%d\n",&visibell);
  391.     fscanf(fp,"font =%d\n",&fntnum);
  392.     fscanf(fp,"keys =");
  393.     fgetc(fp);
  394.  
  395.     for (i = FIRSTOBJ; i <= LASTOBJ; i++) 
  396.     {
  397.       char *found;
  398.       if(i > FIRSTOBJ && i < STARTOBJ) continue;
  399.       if ((menubar[i].ob_type == G_STRING) &&
  400.           (*(char *)menubar[i].ob_spec.free_string != '-'))
  401.       { 
  402.         found = menubar[i].ob_spec.free_string;
  403.         found = found + strlen(found) - 2;
  404.         fread(found,2,1,fp);
  405.       }
  406.     }
  407.     fclose(fp);
  408.   }
  409.  
  410.   update_help();
  411. }
  412.  
  413. void startup()
  414. {
  415.   int i;
  416. #ifdef SYSFONTS
  417.   int j;
  418.   char *tmpfnt;
  419. #endif
  420.   /* start up everything: appl_init, menu, and the like */
  421.  
  422.   appl_id = appl_init();
  423.   if (!rsrc_load("tnftp.rsc")) 
  424.   {
  425.     form_alert(1,"[1][Can't find resource file!][ Quit ]");
  426.     appl_exit();
  427.     exit(0);
  428.   }
  429.   rsrc_gaddr(R_TREE, MENUBAR, &menubar);
  430.  
  431.   /*
  432.      * set caps_table to the base of the table mapping scan codes to
  433.      * ASCII codes when the CAPS-LOCK key is used.
  434.      */
  435.   caps_table = *(((char **)Keytbl((void*)-1L,(void*)-1L,(void*)-1L))+2);
  436.  
  437.   if(_app) menu_bar(menubar, 1);
  438.  
  439.   /* set mouse symbol to arrow */
  440.   graf_mouse(ARROW, NULL);
  441.   mouse = 1;
  442.  
  443.   /* get screen handle and sizes, open virtual workstation */
  444.   phys_handle = graf_handle(&sdummy, &sdummy, &sdummy, &sdummy);
  445.   wind_get(0, WF_WORKXYWH, &scr_x, &scr_y, &scr_w, &scr_h);
  446.   wnum = scr_y;
  447.   work_in[0] = Getrez() + 2;
  448.   for (i=1; i<10; work_in[i++]=1);
  449.   work_in[10] = 2;
  450.   screen_handle = phys_handle;
  451.   v_opnvwk(work_in, &screen_handle, work_out);
  452.   if (screen_handle == 0) 
  453.   {
  454.     /* out of handles */
  455.     form_alert(1,"[1][Sorry, VDI is out of|workstation handles.][ Quit ]");
  456.     appl_exit();
  457.     exit(1);
  458.   }
  459.  
  460.   /* set up screen mfdb.  Set 'ptr' to NULL and VDI does the rest. */
  461.  
  462.   screen_mf.ptr = NULL;
  463.   ncolors = work_out[13];
  464.   /*
  465.          * Load font file(s) if any.
  466.          */
  467.  
  468.   setfonts();
  469.  
  470.   loadfont("windalt.fnt");
  471.   loadfont("windstd.fnt");
  472.   loadfont("windtny.fnt");
  473.   loadfont("windoth.fnt");
  474. #ifndef SYSFONTS
  475.   loadfont("6x7sys.fnt");
  476.   loadfont("8x8sys.fnt");
  477.   loadfont("8x16sys.fnt");
  478. #endif
  479.   if (fontsavail == 0) 
  480.   {
  481.     /* out of handles */
  482.     form_alert(1,"[1][Sorry, No fontfiles found.][ Quit ]");
  483.     appl_exit();
  484.     exit(1);
  485.   }
  486.   /*
  487.      * Disable unused font entries.
  488.      */
  489.   for (i = fontsavail; fontmenuobj[i] != 0; i++) 
  490.   {
  491.     set_menu_string("unavailable font", fontmenuobj[i]);
  492.     objc_change(menubar, fontmenuobj[i], 0, 0, 0, 0, 0, DISABLED, 0);
  493.   }
  494.   fontmenuobj[fontsavail] = 0;
  495.   getcwd(infpath,MAXDIR);
  496.   if(infpath[strlen(infpath)-1] != '\\') strcat(infpath,"\\");
  497.   strcat(infpath,"tnftp.inf");
  498.   load_settings();
  499.   if(!_app) menu_id = menu_register( appl_id, "  Telnet" );
  500. }
  501.  
  502. void finish()
  503. {
  504.   /* close all windows and clean up */
  505.  
  506.   if (!mouse) graf_mouse(M_ON,NULL);
  507.  
  508.   while (wlist) 
  509.   {
  510.     if(wlist->app == FTP)
  511.     {
  512.       if(ftp_data > 0) tcp_close(ftp_data);
  513.       ftpbusy = ftp_data = 0;
  514.     }
  515.     if(wlist->pid)
  516.     {
  517.       tcp_close(wlist->pid);
  518.     }
  519.     w_close(wlist);
  520.   }
  521.  
  522.   menu_bar(menubar, 0);
  523.   v_clsvwk(screen_handle);
  524.   appl_exit();
  525.   exit(0);
  526. }
  527.  
  528. static int i;
  529. int event;
  530. int menuitem = 0;  /* Alt sequence mapped to menu item */
  531. int cx, cy, cw, ch;  /* temps used for form_center */
  532. static int mx, my, mb, mk, m2;  /* mouse coordinates from event_multi */
  533. int clicks;  /* number of clicks seen by evnt_multi. */
  534. int cnt;
  535. int tmp;
  536. OBJECT *obj_tmp;
  537. TEDINFO *ted_tmp;
  538. struct wi_str *wp;
  539. int pastelen;
  540.  
  541. char *shell;  /* name of shell to start in new windows */
  542. extern char *getenv();
  543.  
  544. void main(argc,argv)
  545. int argc;
  546. char *argv[];
  547. {
  548.   timeint = 10;
  549.   wsource = NULL;
  550.   len = 0;
  551.   xsiz = 80;
  552.   ysiz = 24;
  553.   fntnum = 1;
  554.  
  555.   startup();
  556.  
  557.   len = 0;
  558.   pastelen = 10000;
  559.   active = 0;
  560.  
  561.   /* set curfont to the standard font and check that menu item */
  562.   if(fntnum < fontsavail) curfont = fnttbl[fntnum];
  563.   else fntnum = 0;
  564.   objc_change(menubar, fontmenuobj[fntnum], 0, 0, 0, 0, 0, CHECKED, 0);
  565.  
  566.   /* initialize mouse flicker and flourish checkmarks to default values */
  567.   menu_icheck(menubar,MFAST, !fast);
  568.   menu_icheck(menubar,MSFLICKR, mouseflicker);
  569.   menu_icheck(menubar,JERKY, jerky_updates);
  570.   menu_icheck(menubar,WRAP, wrap);
  571.   menu_icheck(menubar,DELMOD, delmode);
  572.   menu_icheck(menubar,AUDIBELL, audibell);
  573.   menu_icheck(menubar,VISIBELL, visibell);
  574.   menu_icheck(menubar,TITLES,titles);
  575.   menu_icheck(menubar,SLIDERS,sliders);
  576.  
  577.   if(_app)
  578.   {
  579.     active = 1; 
  580.  
  581.     /* find the name of our shell: the arg, or $DEFHOST, or have to ask for */
  582.  
  583.     shell = NULL;
  584.     if (argc > 1) shell = argv[1];
  585.     else 
  586.     {
  587.       shell = getenv("DEFHOST");
  588.     }
  589.     hostname[0] = 0;
  590.     if(shell) strcpy(hostname,shell);
  591.  
  592.     if (argc > 2) shell = argv[2];
  593.     else 
  594.     {
  595.       shell = getenv("DEFUSER");
  596.     }
  597.     user[0] = 0;
  598.     if(shell) strcpy(user,shell);
  599.     if (argc > 3) shell = argv[3];
  600.     else 
  601.     {
  602.       shell = getenv("DEFPASSWD");
  603.     }
  604.     passwd[0] = 0;
  605.     if(shell) strcpy(passwd,shell);
  606.  
  607.     newopen();
  608.   }
  609.  
  610.   for (;;) 
  611.   {
  612.     do_multi(0);
  613.   }
  614. }
  615.  
  616. /*
  617.  * s_dial performs a simple dialog with buttons and text only.
  618.  * The strchr of the terminating button is returned.
  619.  * If action == 1, the dialog is displayed.  If action == 2, it is
  620.  * removed.  If action == 3, both operations are done and form_do is
  621.  * called.
  622.  */
  623. int s_dial(tree, action)
  624. int tree, action;
  625. {
  626.   int tmp = 0;
  627.   int cx, cy, cw, ch;
  628.   OBJECT *obj_tmp;
  629.  
  630.   rsrc_gaddr(R_TREE, tree, &obj_tmp);
  631.   form_center(obj_tmp, &cx, &cy, &cw, &ch);
  632.   if (action & 1) 
  633.   {
  634.     form_dial(FMD_START, 0, 0, 20, 10, cx, cy, cw, ch);
  635.     if (!fast) form_dial(FMD_GROW, 0, 0, 20, 10, cx, cy, cw, ch);
  636.     objc_draw(obj_tmp, 0, 5, cx, cy, cw, ch);
  637.   }
  638.   if (action == 3) 
  639.   {
  640.     tmp = form_do(obj_tmp, 0);
  641.   }
  642.   if (action & 2) 
  643.   {
  644.     if (!fast) form_dial(FMD_SHRINK, 0, 0, 20, 10, cx, cy, cw, ch);
  645.     form_dial(FMD_FINISH, 0, 0, 20, 10, cx, cy, cw, ch);
  646.     objc_change(obj_tmp, tmp, 0, cx, cy, cw, ch, NONE, 0);
  647.   }
  648.   return (tmp);
  649. }
  650.  
  651. /*
  652.  * set_menu_string sets the menu string for the specified menu object to
  653.  * newstr.
  654.  */
  655. void set_menu_string(newstr, object)
  656. register char * newstr;
  657. int object;
  658. {
  659.   register char * oldstr;
  660.  
  661.   oldstr = (char *) menubar[object].ob_spec.free_string + 2;
  662.   while (*oldstr && *newstr)
  663.     *oldstr++ = *newstr++;
  664.   if (*oldstr)
  665.     *oldstr = ' ';
  666. }
  667.  
  668. int size_dial(pxsiz,pysiz)
  669. int *pxsiz;
  670. int *pysiz;
  671. {
  672.   /*
  673.          * Enter rows and columns dialog
  674.          */
  675.   int cx, cy, cw, ch;
  676.   int xsiz = *pxsiz;
  677.   int ysiz = *pysiz;
  678.   char *rowstr, *colstr;
  679.   int tmp;
  680.   OBJECT *obj_tmp;
  681.   TEDINFO *ted_tmp;
  682.  
  683.   /* show the mouse if it's hidden */
  684.   /* if mouseflicker is ON, "mouse" will never be false. */
  685.   if (!mouse) 
  686.   {
  687.     mouse = 1;
  688.     graf_mouse(M_ON,NULL);
  689.   }
  690.  
  691.   rsrc_gaddr(R_TREE, WINDSIZE, &obj_tmp);
  692.   ted_tmp = (TEDINFO *) obj_tmp[WINDROWS].ob_spec.tedinfo;
  693.   rowstr = ((char *)ted_tmp->te_ptext);
  694.   if (ysiz < 2) ysiz = 2;
  695.   if (xsiz < 2) xsiz = 2;
  696.   if (ysiz > 99) ysiz = 99;
  697.   if (xsiz > 300) xsiz = 300;
  698.   ted_tmp = (TEDINFO *) obj_tmp[WINDCOLS].ob_spec.tedinfo;
  699.   colstr = ((char *)ted_tmp->te_ptext);
  700.   sprintf(rowstr,"%02d",ysiz);
  701.   sprintf(colstr,"%03d",xsiz);
  702.  
  703.   form_center(obj_tmp, &cx, &cy, &cw, &ch);
  704.   form_dial(FMD_START, 0, 0, 20, 10, cx, cy, cw, ch);
  705.   if (!fast)
  706.     form_dial(FMD_GROW, 0, 0, 20, 10, cx, cy, cw, ch);
  707.   objc_draw(obj_tmp, 0, 5, cx, cy, cw, ch);
  708.   tmp = form_do(obj_tmp, WINDROWS);
  709.   if (!fast)
  710.     form_dial(FMD_SHRINK, 0, 0, 20, 10, cx, cy, cw, ch);
  711.   form_dial(FMD_FINISH, 0, 0, 20, 10, cx, cy, cw, ch);
  712.   objc_change(obj_tmp, tmp, 0, cx, cy, cw, ch, NONE, 0);
  713.   if (tmp == WINDCANC)
  714.     return(FALSE);
  715.   xsiz = xatoi(colstr);
  716.   ysiz = xatoi(rowstr);
  717.   if (xsiz < 10)
  718.     xsiz = 10;
  719.   if (xsiz > 300)
  720.     xsiz = 300;
  721.   if (ysiz < 2)
  722.     ysiz = 2;
  723.   if (ysiz > 99)
  724.     ysiz = 99;
  725.   *pxsiz = xsiz;
  726.   *pysiz = ysiz;
  727.   return (TRUE);
  728. }
  729.  
  730. int xatoi(s)
  731. char *s;
  732. {
  733.   int result = 0;
  734.   char c;
  735.  
  736.   while ((c = *s++) != 0) 
  737.   {
  738.     if (c >= '0' && c <= '9') 
  739.     {
  740.       result *= 10;
  741.       result += (c - '0');
  742.     }
  743.     else return result;
  744.   }
  745.   return result;
  746. }
  747.  
  748. void do_editkeys()
  749. {
  750.   /*
  751.          * Enter function-key-edit dialog
  752.          */
  753.   int cx, cy, cw, ch;
  754.   char *namestr, *keystr;
  755.   int tmp;
  756.   OBJECT *obj_tmp;
  757.   TEDINFO *ted_tmp;
  758.   int cycle, direction;
  759.   char *found;
  760.  
  761.   /* show the mouse if it's hidden */
  762.   /* if mouseflicker is ON, "mouse" will never be false. */
  763.   if (!mouse) 
  764.   {
  765.     mouse = 1;
  766.     graf_mouse(M_ON,NULL);
  767.   }
  768.  
  769.   rsrc_gaddr(R_TREE, EDITKEYS, &obj_tmp);
  770.   ted_tmp = (TEDINFO *) obj_tmp[ITEMNAME].ob_spec.tedinfo;
  771.   namestr = ((char *)ted_tmp->te_ptext);
  772.   ted_tmp = (TEDINFO *) obj_tmp[ITEMKEY].ob_spec.tedinfo;
  773.   keystr = ((char *)ted_tmp->te_ptext);
  774.  
  775.   for (cycle = FIRSTOBJ; cycle <= LASTOBJ; cycle++) 
  776.   {
  777.     if(cycle > FIRSTOBJ && cycle < STARTOBJ) continue;
  778.     /* if it's a string & it doesn't start with dash... */
  779.     if (menubar[cycle].ob_type == G_STRING &&
  780.         (*(char *)menubar[cycle].ob_spec.free_string != '-') &&
  781.         !(menubar[cycle].ob_state & DISABLED))
  782.       break;
  783.   }
  784.   if (cycle > LASTOBJ) return;  /* no strings in the menu?! */
  785.   strncpy(namestr,(char *)menubar[cycle].ob_spec.free_string,20);
  786.   if ((found = strchr((char *)menubar[cycle].ob_spec.free_string, ALTINDICATOR)) != NULL) 
  787.   {
  788.     *keystr = *(found+1);
  789.   }
  790.   else *keystr = ' ';
  791.  
  792.   form_center(obj_tmp, &cx, &cy, &cw, &ch);
  793.   form_dial(FMD_START, 0, 0, 20, 10, cx, cy, cw, ch);
  794.   if (!fast)
  795.     form_dial(FMD_GROW, 0, 0, 20, 10, cx, cy, cw, ch);
  796.   objc_draw(obj_tmp, 0, 5, cx, cy, cw, ch);
  797.   while (1) 
  798.   {
  799.     /* tmp comes back with hi bit set to indicate double-clicks */
  800.     tmp = (form_do(obj_tmp, ITEMKEY) & 0x7fff);
  801.     *keystr = toupper(*keystr);
  802.     /* (do this regardless of what button you used to get out) */
  803.     /* see if you changed the one you were looking at */
  804.     if (found && *(found+1) != *keystr) 
  805.     {
  806.       /* Had a def'n and you changed it. */
  807.       /* un-set the old meaning */
  808.       if (!*keystr || *keystr == ' ') 
  809.       {
  810.         /* changed to nothing */
  811.         *found = ' ';
  812.         *(found+1) = ' ';
  813.       }
  814.       else 
  815.           {
  816.         /* changed to something */
  817.         *(found+1) = *keystr;
  818.       }
  819.     }
  820.     else if (!found && *keystr && *keystr != ' ') 
  821.     {
  822.       /* didn't have a def'n and you gave one */
  823.       for (found = (char *)menubar[cycle].ob_spec.free_string; *found; found++) ;
  824.       *(--found) = *keystr;
  825.       *(--found) = ALTINDICATOR;
  826.     }
  827.     /* else you didn't change it */
  828.  
  829.     if (tmp != ITEMOK) 
  830.     {
  831.       direction = (tmp == ITEMNEXT ? 1 : -1);
  832.       for (cycle += direction;
  833.          cycle <= LASTOBJ && cycle >= FIRSTOBJ;
  834.          cycle += direction) 
  835.       {
  836.         if(cycle > FIRSTOBJ && cycle < STARTOBJ) continue;
  837.         if (menubar[cycle].ob_type == G_STRING &&
  838.             *(char *)menubar[cycle].ob_spec.free_string != '-')
  839.           break;
  840.       }
  841.       if (cycle > LASTOBJ) cycle = FIRSTOBJ;
  842.       else if (cycle < FIRSTOBJ) cycle = LASTOBJ;
  843.  
  844.       strncpy(namestr,(char *)menubar[cycle].ob_spec.free_string,20);
  845.       if ((found = strchr((char *)menubar[cycle].ob_spec.free_string, ALTINDICATOR)) != NULL)
  846.       {
  847.         *keystr = *(found+1);
  848.       }
  849.       else *keystr = ' ';
  850.  
  851.       /* de-select the "next" button, redraw */
  852.       /* should clip the redraw to the parts that matter */
  853.       objc_change(obj_tmp,ITEMNEXT,0,cx,cy,cw,ch,NORMAL,0);
  854.       objc_draw(obj_tmp,0,5,cx,cy,cw,ch);
  855.     }
  856.     else break;
  857.   }
  858.   if (!fast)
  859.     form_dial(FMD_SHRINK, 0, 0, 20, 10, cx, cy, cw, ch);
  860.   form_dial(FMD_FINISH, 0, 0, 20, 10, cx, cy, cw, ch);
  861.   objc_change(obj_tmp, tmp, 0, cx, cy, cw, ch, NONE, 0);
  862.   update_help();
  863. }
  864.  
  865. int get_string(char *prompt, char *string)
  866. {
  867.   int tmp;
  868.   OBJECT *obj_tmp;
  869.   char *ted_tmp;
  870.   int cx, cy, cw, ch;  /* temps used for form_center */
  871.  
  872.   rsrc_gaddr(R_TREE, NEWNAME, &obj_tmp);
  873.   ted_tmp = obj_tmp[PROMPT].ob_spec.free_string;
  874.   strcpy(ted_tmp, prompt);
  875.   strcpy((char*)obj_tmp[FLD1].ob_spec.tedinfo->te_ptext,string);
  876.   form_center(obj_tmp, &cx, &cy, &cw, &ch);
  877.   form_dial(FMD_START, 0, 0, 20, 10, cx, cy, cw, ch);
  878.   if (!fast)
  879.     form_dial(FMD_GROW, 0, 0, 20, 10, cx, cy, cw, ch);
  880.   objc_draw(obj_tmp, 0, 5, cx, cy, cw, ch);
  881.   tmp = form_do(obj_tmp, FLD1);
  882.   if (!fast)
  883.     form_dial(FMD_SHRINK, 0, 0, 20, 10, cx, cy, cw, ch);
  884.   form_dial(FMD_FINISH, 0, 0, 20, 10, cx, cy, cw, ch);
  885.   objc_change(obj_tmp, tmp, 0, cx, cy, cw, ch, NONE, 0);
  886.   if (tmp != OKRENAME) *string = 0;
  887.   else strcpy(string, (char*)obj_tmp[FLD1].ob_spec.tedinfo->te_ptext);
  888.   return tmp;
  889. }
  890.  
  891. int get_host(char *prompt, char *string)
  892. {
  893.   int tmp;
  894.   OBJECT *obj_tmp;
  895.   char *ted_tmp;
  896.   int cx, cy, cw, ch;  /* temps used for form_center */
  897.  
  898.   rsrc_gaddr(R_TREE, NEWCONN, &obj_tmp);
  899.   ted_tmp = obj_tmp[CPROMPT].ob_spec.free_string;
  900.   strcpy(ted_tmp, prompt);
  901.   strcpy((char*)obj_tmp[CFLD1].ob_spec.tedinfo->te_ptext,string);
  902.   form_center(obj_tmp, &cx, &cy, &cw, &ch);
  903.   form_dial(FMD_START, 0, 0, 20, 10, cx, cy, cw, ch);
  904.   if (!fast)
  905.     form_dial(FMD_GROW, 0, 0, 20, 10, cx, cy, cw, ch);
  906.   objc_draw(obj_tmp, 0, 5, cx, cy, cw, ch);
  907.   tmp = form_do(obj_tmp, CFLD1);
  908.   if (!fast)
  909.     form_dial(FMD_SHRINK, 0, 0, 20, 10, cx, cy, cw, ch);
  910.   form_dial(FMD_FINISH, 0, 0, 20, 10, cx, cy, cw, ch);
  911.   objc_change(obj_tmp, tmp, 0, cx, cy, cw, ch, NONE, 0);
  912.   if (tmp != OKFTP && tmp != OKTN) *string = 0;
  913.   else strcpy(string, (char*)obj_tmp[CFLD1].ob_spec.tedinfo->te_ptext);
  914.   return tmp;
  915. }
  916.  
  917. void invert(struct wi_str *wp,int x1,int y1,int x2, int y2)
  918. {
  919.   int t[8];
  920.   int i;
  921.  
  922.   for(i=y1;i<=y2;i++)
  923.   {
  924.     t[0] = t[4] = X0 + wp->m_off;
  925.     t[1] = t[5] = wp->top_y + (wp->font->inc_y * i);
  926.     t[2] = t[6] = t[0] + wp->w - 3*X0;
  927.     t[3] = t[7] = t[1] + wp->font->inc_y - 1;
  928.     if(i==y1) t[0] = t[4] = X0 + wp->m_off + (wp->font->inc_x * x1);
  929.     if(i==y2) t[2] = t[6] = X0 + wp->m_off + (wp->font->inc_x * x2) - 1;
  930.     vro_cpyfm(screen_handle, FM_INVERT, t, (MFDB*)&wp->wi_mf, (MFDB*)&wp->wi_mf);
  931.   }
  932.   w_update(wp, FM_COPY, X0, wp->top_y + (wp->font->inc_y * y1), wp->w, wp->top_y + (wp->font->inc_y * (y2-y1+1)));
  933. }
  934.  
  935. char char_at(struct wi_str *wp, int x_loc, int y_loc)
  936. {
  937.  
  938.   unsigned int width, boffset, count, cur_y, cur_x, i, j;
  939.   register unsigned long mask;
  940.   register unsigned long *dptr;
  941.   register unsigned int shift;
  942.   register FNT *fnt = wp->font;
  943.   static unsigned char pa[32];  /* pixel array containing character image */
  944.  
  945.   cur_x = x_loc * fnt->inc_x + X0;
  946.   cur_y = y_loc * fnt->inc_y + wp->top_y;
  947.  
  948.   width = 2 * wp->wi_mf.wwords;
  949.   boffset = wp->m_off + cur_x + fnt->inc_x - 1;
  950.   dptr = (unsigned long*)(((char*)(wp->wi_mf.ptr)) - 2  + cur_y * width
  951.       + ((boffset >> 4) << 1));
  952.   shift = 15 - (boffset & 15);
  953.   mask = (-1L << (shift + fnt->inc_x)) | ((1 << shift)-1);
  954.   for (count = 0; count < fnt->inc_y; count ++)
  955.   {
  956.     pa[count] = ((*dptr) & (~ mask)) >> shift;
  957.     ((char *) dptr) += width;
  958.   }
  959.   for(i=0;i<fnt->nchars;i++)
  960.   {
  961.     for(j=0;j<fnt->inc_y;j++)
  962.       if(fnt->f_data[i*16 + j] != pa[j]) break;
  963.     if(j == fnt->inc_y) break;
  964.   }
  965.   if(j == fnt->inc_y) return i;
  966.   else
  967.   {
  968.     mask = ~mask >> shift;
  969.     for (count = 0; count < 16; count ++)
  970.     {
  971.       pa[count] = ~pa[count] & mask;
  972.     }
  973.     for(i=0;i<fnt->nchars;i++)
  974.     {
  975.       for(j=0;j<fnt->inc_y;j++)
  976.         if(fnt->f_data[i*16 + j] != pa[j]) break;
  977.       if(j == fnt->inc_y) break;
  978.     }
  979.     if(j == fnt->inc_y) return i;
  980.     else return 0;
  981.   }
  982. }  
  983.  
  984. void save_settings(void)
  985. {
  986.   FILE *fp;
  987.  
  988.   fp = fopen(infpath,"w+");
  989.   if(fp)
  990.   {
  991.     fprintf(fp,"fast = %d\n",fast);
  992.     fprintf(fp,"jerky = %d\n",jerky_updates);
  993.     fprintf(fp,"wrap = %d\n",wrap);
  994.     fprintf(fp,"del/bs = %d\n",delmode);
  995.     fprintf(fp,"mouse = %d\n",mouseflicker);
  996.     fprintf(fp,"sliders = %d\n",sliders);
  997.     fprintf(fp,"titles = %d\n",titles);
  998.     fprintf(fp,"width = %d\n",last_x);
  999.     fprintf(fp,"height = %d\n",last_y);
  1000.     fprintf(fp,"audibell = %d\n",audibell);
  1001.     fprintf(fp,"visibell = %d\n",visibell);
  1002.     fprintf(fp,"font = %d\n",fntnum);
  1003.     fprintf(fp,"keys = ");
  1004.  
  1005.     for (i = FIRSTOBJ; i <= LASTOBJ; i++) 
  1006.     {
  1007.       char *found;
  1008.       if(i > FIRSTOBJ && i < STARTOBJ) continue;
  1009.       if ((menubar[i].ob_type == G_STRING) &&
  1010.           (*(char *)menubar[i].ob_spec.free_string != '-'))
  1011.       {
  1012.         found = menubar[i].ob_spec.free_string;
  1013.         found = found + strlen(found) - 2;
  1014.         fprintf(fp,"%c%c",*found,*(found+1));
  1015.       }
  1016.     }
  1017.     fprintf(fp,"\n");
  1018.     fclose(fp);
  1019.   }
  1020.   else form_alert(1,"[1][Can't write 'tnftp.inf'!][ Quit ]");
  1021. }
  1022.  
  1023. int do_multi(int mode)
  1024. {
  1025.   if (menuitem) 
  1026.   {
  1027.     /* 
  1028.                     * this fork is run when you have faked a menu item with an
  1029.                     * ALT key.  We fall through as if MU_MESAG / MN_SELECTED /
  1030.                     * menuitem came back from AES.
  1031.                     *
  1032.                     * We do not invert any menu titles; below, menu_tnormal
  1033.                     * will not be called because msgbuff[3] contains -1.
  1034.                     */
  1035.     event = MU_MESAG;
  1036.     msgbuff[0] = MN_SELECTED;
  1037.     msgbuff[3] = -1;
  1038.     msgbuff[4] = menuitem;
  1039.     menuitem = 0;
  1040.   }
  1041.   else 
  1042.       {
  1043.     /* if mouseflicker is ON, "mouse" will never be false */
  1044.     if (!mouse) 
  1045.     {
  1046.       if (!wlist) 
  1047.       {
  1048.         /* no windows -- show the mouse */
  1049.         mouse = 1;
  1050.         graf_mouse(M_ON,NULL);
  1051.       }
  1052.       else 
  1053.           {
  1054.         /* get the mouse location so we can wait for it to move */
  1055.         graf_mkstate(&mx,&my,&sdummy,&sdummy);
  1056.       }
  1057.     }
  1058.  
  1059.     /* this is the main event */
  1060.     event = MU_MESAG | MU_KEYBD | MU_BUTTON | MU_TIMER | (mouse ? 0 : MU_M1);
  1061.     event = evnt_multi(event,
  1062.     0x102, 3, 0,
  1063.     1, mx, my, 1, 1,
  1064.     0, 0, 0, 0, 0,
  1065.     msgbuff,
  1066.     timeint, 0,
  1067.     &mx, &my, &mb, &mk,
  1068.     &key, &clicks);
  1069.   }
  1070.  
  1071.   if(event & MU_BUTTON && active && wlist)
  1072.   {
  1073.     evnt_timer(100,0);
  1074.     vq_mouse(screen_handle,&m2,&mx,&my);
  1075.     if(mb == 2 && m2 == 0 && len)
  1076.     {
  1077.       /* stuff from buffer */
  1078.       if(wlist->app == TN)
  1079.         tcp_out(wlist->pid,line,len);
  1080.       else pastelen = 0;
  1081.     }
  1082.     else
  1083.     {
  1084.       if(m2 == 0 && wlist->lastx2 >0)
  1085.       {
  1086.         /* if drag finished copy to linebuffer */
  1087.         int x,xend,y,i,printable;
  1088.         char ch;
  1089.  
  1090.         invert(wlist,wlist->markx1,wlist->marky1,wlist->markx2,wlist->marky2);
  1091.         wlist->lastx2 = -1;
  1092.         wsource = wlist;
  1093.         len=0;
  1094.         x = wsource->markx1;
  1095.         for(y = wsource->marky1;y <= wsource->marky2;y++)
  1096.         {
  1097.           i=len;
  1098.           xend = wsource->x_chrs;
  1099.           if(y == wsource->marky2) xend = wsource->markx2-1;
  1100.           for(;x <= xend;x++)
  1101.           {
  1102.             ch = char_at(wsource, x, y);
  1103.             line[i++] = ch;
  1104.           }
  1105.           line[i]=0;
  1106.           printable = 0;
  1107.           while(i > len)
  1108.           {
  1109.             --i;
  1110.             if(line[i]) printable = 1;
  1111.             else if(printable) line[i] = ' ';
  1112.           }
  1113.           len += (int)strlen(&line[len]);
  1114.           if(ch == 0) line[len++] = '\n';
  1115.           x = 0;
  1116.         }
  1117.       }
  1118.       else if(mb == 1)
  1119.       {
  1120.         int x2,y2;
  1121.  
  1122.         pastelen = 10000;
  1123.  
  1124.         if(mx >= wlist->x && mx <= (wlist->x + wlist->w - X0)
  1125.         && my >= wlist->y && my <= (wlist->y + wlist->h - 2*Y0))
  1126.         {
  1127.           x2 = (mx - wlist->x - X0)/wlist->font->inc_x;
  1128.           y2 = (my - wlist->y - Y0)/wlist->font->inc_y;
  1129.  
  1130.           if(x2 != wlist->lastx2 || y2 != wlist->lasty2)
  1131.           {
  1132.             if(wlist->lastx2 >= 0) invert(wlist,wlist->markx1,wlist->marky1,wlist->markx2,wlist->marky2);
  1133.             else
  1134.             {
  1135.               wlist->markx1 = wlist->markx2 = x2;
  1136.               wlist->marky1 = wlist->marky2 = y2;
  1137.             }
  1138.  
  1139.             if(!wlist->direct)
  1140.             {
  1141.               if(y2 > wlist->marky1 || (y2 == wlist->marky1 && x2 > wlist->markx1))
  1142.               {
  1143.                 invert(wlist,wlist->markx1,wlist->marky1,wlist->markx2=x2,wlist->marky2=y2);
  1144.                 wlist->direct = 0;
  1145.               }
  1146.               else
  1147.               {
  1148.                 invert(wlist,wlist->markx1=x2,wlist->marky1=y2,wlist->markx2,wlist->marky2);
  1149.                 wlist->direct = 1;
  1150.               }
  1151.             }
  1152.             else
  1153.             {
  1154.               if(y2 < wlist->marky2 || (y2 == wlist->marky2 && x2 < wlist->markx2))
  1155.               {
  1156.                 invert(wlist,wlist->markx1=x2,wlist->marky1=y2,wlist->markx2,wlist->marky2);
  1157.                 wlist->direct = 1;
  1158.               }
  1159.               else
  1160.               {
  1161.                 invert(wlist,wlist->markx1,wlist->marky1,wlist->markx2=x2,wlist->marky2=y2);
  1162.                 wlist->direct = 0;
  1163.               }
  1164.             }
  1165.             wlist->lastx2 = x2;
  1166.             wlist->lasty2 = y2;
  1167.             wsource = wlist;
  1168.           }
  1169.         }
  1170.       }
  1171.     }
  1172.   }
  1173.  
  1174.   if (event & MU_M1 && active) 
  1175.   {
  1176.     /* mouse was hidden and moved: show it */
  1177.     mouse = 1;
  1178.     graf_mouse(M_ON,NULL);
  1179.   }
  1180.  
  1181.   if (event & MU_KEYBD && active) 
  1182.   {
  1183.     /*
  1184.                    * Write the key to the pipe of the current window, unless
  1185.                    * it's an ALT key that matches a menu item.
  1186.                    */
  1187.  
  1188.     unsigned char keyval = key & 0xff;
  1189.     long keystrchr = key >> 8;
  1190.  
  1191. #ifdef NET
  1192.     /* lost connection? */      
  1193.     if(active && wlist && wlist->pid == 0)
  1194.     {
  1195.       if(wlist->app == FTP)
  1196.       {
  1197.         if(ftp_data > 0) tcp_close(ftp_data);
  1198.         ftpbusy = ftp_data = 0;
  1199.       }
  1200.       w_close(wlist);
  1201.     }
  1202.     else if (active && keyval == 0) 
  1203.     {
  1204.       /* shortcut or help? */
  1205.         /* do nothing: setting menuitem is all that's needed. */
  1206.         char * found;
  1207.         int i;
  1208.         if(keystrchr == 0x62)
  1209.         {  /* HELP */
  1210.           int tmp;
  1211.           OBJECT *obj_tmp;
  1212.           int i,j;
  1213.           update_help();
  1214.           if((tmp = s_dial(HELPTEXT,3)) != OKHELP)
  1215.           {
  1216.             j = ABOUTTXT;
  1217.             rsrc_gaddr(R_TREE, HELPTEXT, &obj_tmp);
  1218.  
  1219.             for (i = FIRSTOBJ; i <= LASTOBJ; i++) 
  1220.             {
  1221.               if(i > FIRSTOBJ && i < STARTOBJ) continue;
  1222.               if ((menubar[i].ob_type == G_STRING) &&
  1223.                (*(char *)menubar[i].ob_spec.free_string != '-'))
  1224.               {
  1225.                 if(tmp == j) menuitem = i;
  1226.                 j++;
  1227.               }
  1228.             }
  1229.           }
  1230.           key = 0;
  1231.         }
  1232.         else
  1233.         {
  1234.           menuitem = 0;
  1235.  
  1236.           for (i = FIRSTOBJ; i <= LASTOBJ; i++) 
  1237.           {
  1238.             if(i > FIRSTOBJ && i < STARTOBJ) continue;
  1239.             if (menubar[i].ob_type == G_STRING && !(menubar[i].ob_state & DISABLED))
  1240.             {
  1241.               found = strchr(menubar[i].ob_spec.free_string, ALTINDICATOR);
  1242.               if (found != NULL && *(found+1) == caps_table[keystrchr])
  1243.               {
  1244.                 menuitem = i;
  1245.                 key = 0;
  1246.                 break;
  1247.               }
  1248.             }
  1249.           }
  1250.         }
  1251. #endif
  1252.     }
  1253.     {
  1254.         if (active && wlist && key)
  1255.         {
  1256.           if(keyval == 0x13)
  1257.             wlist->recv_flag = 0;
  1258.           if(keyval == 0x11)
  1259.             wlist->recv_flag = 1;
  1260.  
  1261.  
  1262.           if(wlist->app == TN) tnet(wlist, key);
  1263.           else handle_key(wlist, key & 0xff);
  1264.         }
  1265.     }
  1266.   } /* if no key */
  1267.   else if(active && wlist && wlist->app == FTP && pastelen < len)
  1268.   {
  1269.       handle_key(wlist, line[pastelen++]);
  1270.   }
  1271. #ifndef NET
  1272.     {
  1273.       i=0;      
  1274.       while(Bconstat(AUX) && i < 99)
  1275.         buf[i++] = Cauxin() & 0x7f;
  1276.       buf[i]=0;
  1277.       if (wlist && i) 
  1278.       {
  1279.         w_output(wlist,(char *)buf,i);
  1280.         /* else ignore the key (process can't accept output) */
  1281.       }
  1282.       /* else there are no windows, thus nowhere to write to */
  1283.     }
  1284. #endif
  1285. #ifdef NET
  1286.     if (active && wlist)
  1287.     {
  1288.       struct wi_str *wlistsave;
  1289.  
  1290.       wp = wlistsave = wlist;
  1291.  
  1292.       do 
  1293.       {
  1294.         if(wp->pid != 0 && wp->recv_flag)
  1295.         {
  1296.           if(wp->app == TN)
  1297.           {
  1298.             if(upcall(wp) < 0)
  1299.             {
  1300.               tcp_close(wp->pid);
  1301.               w_info(wp,"<Status: connection closed.>");
  1302.               wp->pid = 0;
  1303.             }
  1304.           }
  1305.           else if(wp->app == FTP)
  1306.           {
  1307.             if(ftp_application(wp) == 2)
  1308.             {
  1309.               tcp_close(wp->pid);
  1310.               if(ftp_data > 0) tcp_close(ftp_data);
  1311.               w_info(wp,"<Status: connection closed.>");
  1312.               wp->pid = ftpbusy = ftp_data = 0;
  1313.             }
  1314.           }
  1315.         }
  1316.         else tcp_stat(0,NULL);  /* keep network alive */
  1317.         wp = wp->next;
  1318.         if(wlistsave != wlist) wp = wlistsave = wlist;
  1319.       } 
  1320.       while (wlist && wp != wlist);
  1321.     }
  1322.     else tcp_stat(0,NULL); /* keep network alive */
  1323. #endif
  1324.  
  1325.     if (event & MU_MESAG) 
  1326.     {
  1327.       switch (msgbuff[0]) 
  1328.       {
  1329.       case MN_SELECTED:
  1330.         switch (msgbuff[4]) 
  1331.         {
  1332.         case MENUEDIT:
  1333.           do_editkeys();
  1334.           break;
  1335.         case WINRESIZ:
  1336.           if (!wlist) break;
  1337.           xsiz = wlist->x_chrs;
  1338.           ysiz = wlist->y_chrs;
  1339.           if (!size_dial(&xsiz,&ysiz)) break;
  1340.           if (w_resize(wlist, xsiz, ysiz, 
  1341.           wlist->sliders, wlist->titles, 0)) 
  1342.           {
  1343.             /* lost the window! Do what we can... */
  1344.           }
  1345.           break;
  1346.  
  1347.           /* "refont" -- reopen the window in the selected font */
  1348.         case REFONT:
  1349.           if (!wlist) break;
  1350.           if (w_resize(wlist, wlist->x_chrs, wlist->y_chrs,
  1351.           wlist->sliders, wlist->titles, 1)) 
  1352.           {
  1353.             /* lost the window! Do what we can... */
  1354.           }
  1355.           break;
  1356.  
  1357.         case FQUIT:
  1358.           if(_app) finish();
  1359.           break;
  1360.  
  1361.         case DABOUT:
  1362.           s_dial(ABOUT, 3);
  1363.           break;
  1364.  
  1365.         case SAVE:
  1366.           save_settings();
  1367.           break;
  1368.  
  1369.         case LOAD:
  1370.           load_settings();
  1371.           break;
  1372.  
  1373.         case WRENAME:
  1374.           if (!wlist) break;  /* no window to rename */
  1375.           rsrc_gaddr(R_TREE, NEWNAME, &obj_tmp);
  1376.           ted_tmp = (TEDINFO *) obj_tmp[FLD1].ob_spec.tedinfo;
  1377.           strncpy(ted_tmp->te_ptext, wlist->name,20);
  1378.           form_center(obj_tmp, &cx, &cy, &cw, &ch);
  1379.           form_dial(FMD_START, 0, 0, 20, 10, cx, cy, cw, ch);
  1380.           if (!fast)
  1381.             form_dial(FMD_GROW, 0, 0, 20, 10, cx, cy, cw, ch);
  1382.           objc_draw(obj_tmp, 0, 5, cx, cy, cw, ch);
  1383.           tmp = form_do(obj_tmp, FLD1);
  1384.           if (!fast)
  1385.             form_dial(FMD_SHRINK, 0, 0, 20, 10, cx, cy, cw, ch);
  1386.           form_dial(FMD_FINISH, 0, 0, 20, 10, cx, cy, cw, ch);
  1387.           objc_change(obj_tmp, tmp, 0, cx, cy, cw, ch, NONE, 0);
  1388.           if (tmp == OKRENAME)
  1389.             w_rename(wlist, (char *) ted_tmp->te_ptext);
  1390.           break;
  1391.  
  1392.         case JERKY:
  1393.           jerky_updates = !jerky_updates;
  1394.           menu_icheck(menubar,JERKY, jerky_updates);
  1395.           break;
  1396.  
  1397.         case WRAP:
  1398.           wrap = !wrap;
  1399.           if(wlist) wlist->discard = !wrap;
  1400.           menu_icheck(menubar,WRAP, wrap);
  1401.           break;
  1402.  
  1403.         case DELMOD:
  1404.           delmode = !delmode;
  1405.           menu_icheck(menubar,DELMOD, delmode);
  1406.           break;
  1407.  
  1408.         case MSFLICKR:
  1409.           mouseflicker = !mouseflicker;
  1410.           menu_icheck(menubar,MSFLICKR, mouseflicker);
  1411.           break;
  1412.  
  1413.         case MFAST:
  1414.           menu_icheck(menubar, MFAST, fast);
  1415.           fast = !fast;
  1416.           break;
  1417.  
  1418.         case FNT8X8:
  1419.         case FNT8X16:
  1420.         case FNT6X7:
  1421.         case FNTOWN:
  1422.         case FNTALT:
  1423.         case FNTTNY:
  1424.         case FNTOTH:
  1425.           /* Add new font menu items here! */
  1426.           for (cnt = 0; fontmenuobj[cnt] != 0; cnt++) 
  1427.           {
  1428.             if (fontmenuobj[cnt] != msgbuff[4]) 
  1429.             {
  1430.               /* un-check any font that isn't the new one */
  1431.               objc_change(menubar, fontmenuobj[cnt],
  1432.               0, 0, 0, 0, 0, NONE, 0);
  1433.             }
  1434.             else 
  1435.             {
  1436.               /* this is the new font: set it & checkmark it */
  1437.               objc_change(menubar, msgbuff[4],
  1438.               0, 0, 0, 0, 0, CHECKED, 0);
  1439.               curfont = fnttbl[cnt];
  1440.               fntnum = cnt;
  1441.             }
  1442.           }
  1443.           break;
  1444.  
  1445.         case AUDIBELL:
  1446.           audibell = !audibell;
  1447.           objc_change(menubar, AUDIBELL, 0, 0, 0, 0, 0,
  1448.           audibell? CHECKED: 0, 0);
  1449.           break;
  1450.  
  1451.         case VISIBELL:
  1452.           visibell = !visibell;
  1453.           objc_change(menubar, VISIBELL, 0, 0, 0, 0, 0,
  1454.           visibell? CHECKED: 0, 0);
  1455.           break;
  1456.  
  1457.         case SHRNKWIN:  /* Shrink window to iconic size */
  1458.           if (wlist) 
  1459.           {
  1460.             w_shrink(wlist);
  1461.           }
  1462.           break;
  1463.  
  1464.         case BOTTOMTO:  /* send bottom window to top */
  1465.           w_bottom();
  1466.           break;
  1467.  
  1468.         case HIDEWIN:  /* send top window to bottom */
  1469.           w_hide();
  1470.           break;
  1471.  
  1472.         case OSIZEWIN:
  1473.           if (wlist) 
  1474.           {
  1475.             w_full(wlist);
  1476.           }
  1477.           break;
  1478.  
  1479.         case SLIDERS:  /* toggle sliders for new windows */
  1480.           sliders = !sliders;
  1481.           menu_icheck(menubar, SLIDERS, sliders);
  1482.           break;
  1483.  
  1484.         case TITLES:  /* enable/disable window headers */
  1485.           titles = !titles;
  1486.           menu_icheck(menubar, TITLES, titles);
  1487.           break;
  1488.  
  1489.         case SETGADG: 
  1490.           {  /* set gadgets based on settings */
  1491.             if (!wlist) break;
  1492.  
  1493.             if (w_resize(wlist, wlist->x_chrs, wlist->y_chrs,
  1494.             sliders, titles, 0)) 
  1495.             {
  1496.               /* list the window! */
  1497.             }
  1498.             /* make this the "main" style for this window */
  1499.             wlist->wi_mainstyle = wlist->wi_style;
  1500.             break;
  1501.           }
  1502.  
  1503.         case GADGETS: 
  1504.           {  /* toggle gadgets for this window */
  1505.             int tmpslide, tmptitle;
  1506.  
  1507.             if (!wlist) break;
  1508.             /*
  1509.                                      * If your original ("main") style includes all sliders,
  1510.                                      * this toggles between all and nothing.  Otherwise,
  1511.                                      * it toggles between your "main" style and everything.
  1512.                                      */
  1513.             if (wlist->wi_mainstyle == (WI_WITHSLD|WI_WITHTITLE)) 
  1514.             {
  1515.               /* main style is full style */
  1516.               if (wlist->wi_style == wlist->wi_mainstyle) 
  1517.               {
  1518.                 /* already all, so make it none */
  1519.                 tmpslide = 0;
  1520.                 tmptitle = 0;
  1521.               }
  1522.               else 
  1523.               {
  1524.                 tmpslide = 1;
  1525.                 tmptitle = 1;
  1526.               }
  1527.             }
  1528.             else if (wlist->wi_style != wlist->wi_mainstyle) 
  1529.             {
  1530.               /* reset back to mainstyle */
  1531.               tmpslide = (wlist->wi_mainstyle & WI_WITHSLD);
  1532.               tmptitle = (wlist->wi_mainstyle & WI_WITHTITLE);
  1533.             }
  1534.             else 
  1535.                 {
  1536.               /* add sliders and title bar */
  1537.               tmpslide = 1;
  1538.               tmptitle = 1;
  1539.             }
  1540.             if (w_resize(wlist, wlist->x_chrs, wlist->y_chrs,
  1541.             tmpslide, tmptitle, 0)) 
  1542.             {
  1543.               /* lost the window! Do what we can... */
  1544.             }
  1545.             break;
  1546.           }
  1547.  
  1548.         case SETOTHER:  /* set the "other" size */
  1549.           size_dial(&last_x,&last_y);
  1550.           break;
  1551.  
  1552.         case NEWWIND:  /* new window 24x80*/
  1553.         case NEWOTHER:  /* new other */
  1554.           if (msgbuff[4] == NEWWIND) 
  1555.           {
  1556.             /* default window size */
  1557.             xsiz = 80;
  1558.             ysiz = 24;
  1559.           }
  1560.           else if (msgbuff[4] == NEWOTHER) 
  1561.           {
  1562.             xsiz = last_x;
  1563.             ysiz = last_y;
  1564.           }
  1565.  
  1566.           /* find the name of our shell: the arg, or $SHELL, or MWINIT.PRG */
  1567.  
  1568.           newopen();
  1569.           break;
  1570.         case CLOSE:
  1571.           if (!wlist) break;
  1572.           if(wlist->pid)
  1573.           {
  1574.             tcp_close(wlist->pid);
  1575.             if(wlist->app == FTP)
  1576.             {
  1577.               if(ftp_data > 0) tcp_close(ftp_data);
  1578.               ftpbusy = ftp_data = 0;
  1579.             }
  1580.           } 
  1581.           w_close(wlist);
  1582.           break;
  1583.         }
  1584.         if (msgbuff[3] != -1) menu_tnormal(menubar, msgbuff[3], 1);
  1585.         break;
  1586.  
  1587.       case WM_NEWTOP:
  1588.         /* one of my windows is newly the top window */
  1589.         /* I don't happen to care... Do I? */
  1590.         break;
  1591.  
  1592.       case WM_TOPPED:
  1593.         if (!wlist) break;
  1594.         wp = wlist;
  1595.         do                 
  1596.         {
  1597.           if (wp->aes_handle == msgbuff[3]) 
  1598.           {
  1599.             w_top(wp);
  1600.             break;
  1601.           }
  1602.           wp = wp->next;
  1603.         } 
  1604.         while (wp != wlist);
  1605.         break;
  1606.  
  1607.       case WM_SIZED:
  1608.       case WM_MOVED:
  1609.         if (!wlist) break;
  1610.         wp = wlist;
  1611.         do 
  1612.         {
  1613.           if (wp->aes_handle == msgbuff[3]) 
  1614.           {
  1615.             w_move(wp, msgbuff[4], msgbuff[5], msgbuff[6], msgbuff[7]);
  1616.             break;
  1617.           }
  1618.           wp = wp->next;
  1619.         } 
  1620.         while (wp != wlist);
  1621.         break;
  1622.  
  1623.       case AC_OPEN:
  1624.         if( msgbuff[4] == menu_id )
  1625.         {
  1626.           if (!wlist || active)
  1627.           {
  1628.             /* default window size */
  1629.             xsiz = 80;
  1630.             ysiz = 24;
  1631.  
  1632.             if(hostname[0] == 0)
  1633.             {
  1634.              shell = getenv("DEFHOST");
  1635.              if(shell) strcpy(hostname,shell);
  1636.             }
  1637.             newopen();
  1638.           }
  1639.           else
  1640.           {
  1641.             if(!active && wlist)
  1642.             {
  1643.               wp = wlist;
  1644.               do 
  1645.               {
  1646.                 int tmp_x, tmp_y, tmp_w, tmp_h;
  1647.  
  1648.                 wind_calc(0, wp->wi_style, wp->x, wp->y, wp->w, wp->h, &tmp_x, &tmp_y, &tmp_w, &tmp_h);
  1649.                 if (!fast)
  1650.                   graf_growbox(0, 0, 20, 10, tmp_x, tmp_y, tmp_w, tmp_h);
  1651.                 wp->aes_handle = wind_create(wp->wi_style, tmp_x, tmp_y, tmp_w, tmp_h);
  1652.                 if (wp->aes_handle < 0) 
  1653.                 {
  1654.                   form_alert(1, "[1][Sorry, GEM has|no more windows|for us...][Ok]");
  1655.                 }
  1656.                 wind_open(wp->aes_handle, tmp_x, tmp_y, tmp_w, tmp_h);
  1657.                 if (wp->wi_style & NAME) 
  1658.                 {
  1659.                   wind_set(wp->aes_handle, WF_NAME, wp->name, 0, 0);
  1660.                   wind_set(wp->aes_handle, WF_INFO, wp->info, 0, 0);
  1661.                 }
  1662.                 setvslide(wp);
  1663.                 sethslide(wp);
  1664.                 wp = wp->next;
  1665.               } 
  1666.               while (wp != wlist);
  1667.               wlist = wlist->prev;
  1668.             }
  1669.           }
  1670.         }
  1671.         active = 1;
  1672.         break;
  1673.  
  1674.       case AC_CLOSE:
  1675.         if( msgbuff[3] == menu_id )
  1676.         {
  1677.           active = 0;
  1678.         }
  1679.         break;
  1680.  
  1681.       case WM_CLOSED:
  1682.         if (!wlist) break;
  1683.         wp = wlist;
  1684.         do 
  1685.         {
  1686.           if (wp->aes_handle == msgbuff[3]) 
  1687.           {
  1688.             break;
  1689.           }
  1690.           wp = wp->next;
  1691.         } 
  1692.         while (wp != wlist);
  1693.         if(wp->pid)
  1694.         {
  1695.           tcp_close(wp->pid);
  1696.           if(wlist->app == FTP)
  1697.           {
  1698.             if(ftp_data > 0) tcp_close(ftp_data);
  1699.             ftpbusy = ftp_data = 0;
  1700.           }
  1701.         }
  1702.         w_close(wp);
  1703.         break;
  1704.  
  1705.       case WM_REDRAW: 
  1706.         {
  1707.           if (!wlist) break;
  1708.           wp = wlist;
  1709.           do 
  1710.           {
  1711.             if (wp->aes_handle == msgbuff[3]) 
  1712.             {
  1713.               w_redraw(wp,FM_COPY, msgbuff[4], msgbuff[5],
  1714.               msgbuff[6], msgbuff[7]);
  1715.               break;
  1716.             }
  1717.             wp = wp->next;
  1718.           } 
  1719.           while (wp != wlist);
  1720.           break;
  1721.         }
  1722.  
  1723.       case WM_FULLED:
  1724.         if (!wlist) break;
  1725.         wp = wlist;
  1726.         do 
  1727.         {
  1728.           if (wp->aes_handle == msgbuff[3]) 
  1729.           {
  1730.             w_full(wp);
  1731.             break;
  1732.           }
  1733.           wp = wp->next;
  1734.         } 
  1735.         while (wp != wlist);
  1736.         break;
  1737.  
  1738.       case WM_ARROWED:
  1739.         if (!wlist) break;
  1740.         wp = wlist;
  1741.         do 
  1742.         {
  1743.           if (wp->aes_handle == msgbuff[3]) 
  1744.           {
  1745.             w_arrow(wp,msgbuff[4]);
  1746.             break;
  1747.           }
  1748.           wp = wp->next;
  1749.         } 
  1750.         while (wp != wlist);
  1751.         break;
  1752.  
  1753.       case WM_HSLID:
  1754.       case WM_VSLID:
  1755.         if (!wlist) break;
  1756.         wp = wlist;
  1757.         do 
  1758.         {
  1759.           if (wp->aes_handle == msgbuff[3]) 
  1760.           {
  1761.             w_slide(wp, msgbuff[0] == WM_HSLID, msgbuff[4]);
  1762.             break;
  1763.           }
  1764.           wp = wp->next;
  1765.         } 
  1766.         while (wp != wlist);
  1767.         break;
  1768.       }
  1769.     }
  1770.     return 0;
  1771.   }
  1772.  
  1773.   void newopen(void)
  1774.   {
  1775.     i = get_host("Hostname:",hostname);
  1776.     if(i == OKFTP || i == OKTN)
  1777.     {
  1778.       if(i != OKFTP || !ftpbusy)
  1779.       {
  1780.         if(i == OKTN) sprintf(data," TUW-Telnet %s (%s) ",VERSION,hostname);
  1781.         else sprintf(data," TUW-Ftp %s (%s) ",VERSION,hostname);
  1782.         wnum += WOFFSET;
  1783.         if(wnum > scr_y+(scr_w/2)) wnum = scr_y;
  1784.  
  1785.         if (w_open(data, wnum, wnum, xsiz, ysiz, sliders, titles, curfont)) 
  1786.         {
  1787.           /* can't open the window */
  1788.         }
  1789.         else
  1790.         {
  1791.           if(i == OKTN)
  1792.           { 
  1793.             wlist->pid = connect(0,hostname,TELNET_PORT);
  1794.             wlist->app = TN;
  1795.           }
  1796.           else
  1797.           {
  1798.             wlist->app = FTP;
  1799.             wlist->pid = ftp_ctl = connect(0, hostname,FTP_CTL);
  1800.             if(ftp_ctl > 0) ftpbusy = 1;
  1801.             ftpinit(wlist,user,passwd);
  1802.           }               
  1803.         }
  1804.       }
  1805.     }
  1806.   }
  1807.